home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_10_03 / 1003106a < prev    next >
Text File  |  1992-01-11  |  7KB  |  217 lines

  1.  
  2.  /************************************************************
  3.   *  Program: CMENU Menu Compiler
  4.   *  Module: cmenu3.c
  5.   *      Menu Compiler:
  6.   *      Token Processing Functions
  7.   *  Written by: Leor Zolman, 7/91
  8.   ************************************************************/
  9.  
  10.  #include "cmenu.h"
  11.  #include "ccmenu.h"
  12.  
  13.  #include <ctype.h>
  14.  
  15.  static int unget_flag = FALSE;
  16.  static int unget_token;
  17.  static char unget_tparam[MAX_CMD];
  18.  static int unget_vparam;
  19.  
  20.  static int quoted_text;
  21.  
  22.  #if __STDC__
  23.  char *getword(void);
  24.  int matchkey(char *);
  25.  #else
  26.  char *getword();
  27.  int matchkey();
  28.  #endif
  29.  
  30.  /************************************************************
  31.   * ungettok():
  32.   *  Push a token back into the input stream, to
  33.   *  be returned by the following call to gettok().
  34.   *  Only one level of push-back is supported; any attempt to
  35.   *  push back a token when there is already one pushed back
  36.   *  draws an "internal error" diagnostic.
  37.   ************************************************************/
  38.  
  39.  Void ungettok(tok)
  40.  int tok;
  41.  {
  42.      if (unget_flag)                 /* can't "unget" more than 1 item! */
  43.          fatalerr("internal error: ungettok() overflow");
  44.      
  45.      unget_flag = TRUE;
  46.      unget_token = tok;
  47.      unget_vparam = vparam;
  48.      strcpy(unget_tparam, tparam);
  49.      return;
  50.  }
  51.  
  52.  
  53.  /************************************************************
  54.   * gettok():
  55.   *  Read a token from the source input stream.
  56.   *  If the token is a reserved word, the appropriate token
  57.   *      value is returned.
  58.   *  If the token is a string, the global "tparam" is set
  59.   *      to the text of the string. White space within the
  60.   *      string is only recognized if double quote ("...")
  61.   *      characters are used to delimit the string.
  62.   *      T_STRING is returned.
  63.   *  If the token is a numeric value, the global "vparam"
  64.   *      is set to the integer value specified, and
  65.   *      T_VALUE is returned.
  66.   *  Returns T_EOF on end-of-file.
  67.   ************************************************************/
  68.  
  69.  int gettok()
  70.  {
  71.      register c;
  72.      char nexttok[MAX_CMD];
  73.      char *wordp;
  74.      
  75.      if (unget_flag)                    /* was a token "pushed back"?   */
  76.      {                          /* yes. set the pushed-back values and  */
  77.          vparam = unget_vparam;                         /* attributes   */
  78.          strcpy(tparam, unget_tparam);                  /* clear the    */
  79.          unget_flag = FALSE;                            /* flag         */
  80.          return unget_token;                    /* return pushed token  */
  81.      }
  82.      
  83.      *tparam = '\0';                                /* clear parameter  */
  84.      vparam = 0;                                    /* value registers  */
  85.  
  86.      if (!*(wordp = getword()))                     /* get a token.     */
  87.          return token = T_EOF;                      /* End of file      */
  88.      
  89.      if (quoted_text)                               /* string enclosed  */
  90.      {                                              /* in quotes?       */
  91.          strcpy(tparam, wordp);
  92.          return T_STRING;
  93.      }
  94.  
  95.      if (!strcmp(wordp, ":"))                       /* colon is special */
  96.          return T_COLON;                            /* (non-alphabetic) */
  97.  
  98.      if (c = matchkey(wordp))                       /* reserved word?   */
  99.          return c;                                  /* yes, just return */
  100.  
  101.      if (isdigit(*wordp))                       /* handle numeric value */
  102.      {
  103.          vparam = atoi(wordp);
  104.          return T_VALUE;
  105.      }
  106.      else
  107.      {
  108.          strcpy(tparam, wordp);
  109.          return T_STRING;
  110.      }
  111.  }
  112.  
  113.  
  114.  /************************************************************
  115.   * getword():
  116.   *  Read the next syntactic object from the input stream,
  117.   *  and return a pointer to it.
  118.   *  Return pointer to a null string on EOF.
  119.   *  If object is a quoted string, drop the quotes and
  120.   *      set the quoted_text flag (preserve whitespace).
  121.   *  Otherwise strip all whitespace, commas and comments,
  122.   *      return pointer to next word/number.
  123.   *  Track current line number by incrementing lineno
  124.   *      on each newline encountered.
  125.   ************************************************************/
  126.  
  127.  char *getword()
  128.  {
  129.      static char tok[MAX_CMD];
  130.      char quote_char;
  131.      register c,i;
  132.      
  133.      quoted_text = FALSE;
  134.      *tok = '\0';
  135.  
  136.      while ((c = getc(fp)) != EOF)
  137.      {
  138.          if (c == '\n')                         /* bump line number if  */
  139.              lineno++;                          /* newline encountered  */
  140.          
  141.          if (isspace(c))                        /* skip all whitespace  */
  142.              continue;
  143.  
  144.          if (c == ',' || c == ';')              /* legal separators: ,; */
  145.              continue;
  146.                  
  147.          if (c == ':')                          /* special case: colon  */
  148.              return ":";
  149.          
  150.          if (c == '#')                          /* process comment      */
  151.          {                                  /* wait for newline or EOF  */
  152.              while(c = getc(fp))
  153.              {
  154.                  if (c == EOF)
  155.                      break;
  156.                  if (c == '\n')
  157.                  {
  158.                      lineno++;
  159.                      break;
  160.                  }
  161.              }
  162.              continue;                          /* then get next token  */
  163.          }
  164.          
  165.          if (c == '"' || c == '\'')             /* quoted string?       */
  166.          {
  167.              quoted_text = TRUE;
  168.              quote_char = c;
  169.              for (i = 0; ;i++)
  170.              {
  171.                  switch (c = getc(fp))
  172.                  {
  173.                      case '\n':
  174.                          fatalerr("Unterminated string");
  175.                          return NULL;
  176.                          
  177.                      case EOF:
  178.                          fatalerr("Unterminated string (line %d)",
  179.                                  lineno);
  180.                          return NULL;
  181.                      
  182.                      case '"':
  183.                      case '\'':
  184.                          if (c == quote_char)
  185.                          {
  186.                              tok[i] = '\0';
  187.                              return tok;
  188.                          }
  189.  
  190.                      default:
  191.                          if (i == MAX_CMD)
  192.                          {
  193.                              tok[i - 1] = '\0';
  194.                              fatalerr("String too long (max %d chars)",
  195.                                  MAX_CMD);
  196.                              return NULL;
  197.                          }
  198.                          tok[i] = c;
  199.                  }
  200.              }
  201.          }
  202.          
  203.          tok[0] = c;
  204.          for (i = 1; (c = getc(fp)) != EOF; i++)
  205.              if (isspace(c) || c == ';' || c == ','
  206.                      || c == ':')
  207.                  break;
  208.              else
  209.                  tok[i] = tolower(c);
  210.          tok[i] = '\0';
  211.          ungetc(c, fp);
  212.          break;
  213.      }
  214.      return tok;
  215.  }
  216.  
  217.